package com.ruoyi.caipiao.service.impl;

import java.util.*;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.caipiao.domain.CaipiaoPl5Stat1;
import com.ruoyi.caipiao.domain.CaipiaoPl5Stat2;
import com.ruoyi.caipiao.dto.req.YuReqDTO;
import com.ruoyi.caipiao.mapper.CaipiaoPl5Stat1Mapper;
import com.ruoyi.caipiao.mapper.CaipiaoPl5Stat2Mapper;
import com.ruoyi.caipiao.service.ICaipiaoPl5Stat1Service;
import com.ruoyi.caipiao.service.ICaipiaoPl5Stat2Service;
import com.ruoyi.caipiao.utils.MapValueSortUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.caipiao.mapper.CaipiaoPl5HistoryMapper;
import com.ruoyi.caipiao.domain.CaipiaoPl5History;
import com.ruoyi.caipiao.service.ICaipiaoPl5HistoryService;
import org.springframework.web.client.RestTemplate;

/**
 * 排列5历史开奖Service业务层处理
 *
 * @author ruoyi
 * @date 2025-03-02
 */
@Slf4j
@Service
public class CaipiaoPl5HistoryServiceImpl extends ServiceImpl<CaipiaoPl5HistoryMapper, CaipiaoPl5History> implements ICaipiaoPl5HistoryService {
    @Autowired
    private CaipiaoPl5HistoryMapper caipiaoPl5HistoryMapper;
    RestTemplate restTemplate;
    static String URL = "https://webapi.sporttery.cn/gateway/lottery/getHistoryPageListV1.qry?gameNo=350133&provinceId=0&pageSize=100&isVerify=1&pageNo=";

    @Override
    public List<String> list(Long qs, Integer size) {
        return caipiaoPl5HistoryMapper.list(qs, size);
    }

    @Override
    public Long getMaxQs() {
        return caipiaoPl5HistoryMapper.selectMaxQs();
    }

    @Override
    public int allHistory() {
        new Thread(() -> {
            log.info("开始爬取排列5历史开奖数据");
            Long maxQs = caipiaoPl5HistoryMapper.selectMaxQs();
            restTemplate = new RestTemplate();
            for (int i = 1; i < 500; i++) {
                String url = URL + i;
                List<CaipiaoPl5History> pl5Nums = getPl5Num(url, maxQs);
                if (CollectionUtil.isEmpty(pl5Nums)) {
                    break;
                }
                caipiaoPl5HistoryMapper.insertCaipiaoPl5HistoryBatch(pl5Nums);
                if (maxQs != null && pl5Nums.get(pl5Nums.size() - 1).getQs() == maxQs.longValue()) {
                    break;
                }
            }
            log.info("结束爬取排列5历史开奖数据");
        }).start();

        return 0;
    }

    private List<CaipiaoPl5History> getPl5Num(String url, Long maxQs) {
        List<CaipiaoPl5History> list = new ArrayList<>();
        String forObject = restTemplate.getForObject(url, String.class);
        JSONObject entries = JSONUtil.parseObj(forObject);
        if ((boolean) entries.get("success")) {
            JSONObject value = (JSONObject) entries.get("value");
            JSONArray jsonArray = (JSONArray) value.get("list");
            if (jsonArray.isEmpty()) {
                log.info("采集完成");
                return null;
            }
            for (Object obj : jsonArray) {
                JSONObject jsonObject = (JSONObject) obj;
                String hm = (String) jsonObject.get("lotteryDrawResult");
                String rq = (String) jsonObject.get("lotteryDrawTime");
//                String str = rq.replace("-", "") + "-" + hm.replace(" ", "");
                CaipiaoPl5History caipiaoPl5History = new CaipiaoPl5History();
                caipiaoPl5History.setQs(Long.parseLong(rq.replace("-", "")));
                caipiaoPl5History.setKjNum(hm.replace(" ", ""));
                if (maxQs != null && maxQs.longValue() == caipiaoPl5History.getQs()) {
                    return list;
                }
                list.add(caipiaoPl5History);
            }
        }
        return list;
    }

    /**
     * 查询排列5历史开奖
     *
     * @param qs 排列5历史开奖主键
     * @return 排列5历史开奖
     */
    @Override
    public CaipiaoPl5History selectCaipiaoPl5HistoryByQs(Long qs) {
        return caipiaoPl5HistoryMapper.selectCaipiaoPl5HistoryByQs(qs);
    }

    /**
     * 查询排列5历史开奖列表
     *
     * @param caipiaoPl5History 排列5历史开奖
     * @return 排列5历史开奖
     */
    @Override
    public List<CaipiaoPl5History> selectCaipiaoPl5HistoryList(CaipiaoPl5History caipiaoPl5History) {
        return caipiaoPl5HistoryMapper.selectCaipiaoPl5HistoryList(caipiaoPl5History);
    }

    /**
     * 新增排列5历史开奖
     *
     * @param caipiaoPl5History 排列5历史开奖
     * @return 结果
     */
    @Override
    public int insertCaipiaoPl5History(CaipiaoPl5History caipiaoPl5History) {
        return caipiaoPl5HistoryMapper.insertCaipiaoPl5History(caipiaoPl5History);
    }

    /**
     * 修改排列5历史开奖
     *
     * @param caipiaoPl5History 排列5历史开奖
     * @return 结果
     */
    @Override
    public int updateCaipiaoPl5History(CaipiaoPl5History caipiaoPl5History) {
        return caipiaoPl5HistoryMapper.updateCaipiaoPl5History(caipiaoPl5History);
    }

    /**
     * 批量删除排列5历史开奖
     *
     * @param qss 需要删除的排列5历史开奖主键
     * @return 结果
     */
    @Override
    public int deleteCaipiaoPl5HistoryByQss(Long[] qss) {
        return caipiaoPl5HistoryMapper.deleteCaipiaoPl5HistoryByQss(qss);
    }

    /**
     * 删除排列5历史开奖信息
     *
     * @param qs 排列5历史开奖主键
     * @return 结果
     */
    @Override
    public int deleteCaipiaoPl5HistoryByQs(Long qs) {
        return caipiaoPl5HistoryMapper.deleteCaipiaoPl5HistoryByQs(qs);
    }

    @Autowired
    ICaipiaoPl5Stat1Service iCaipiaoPl5Stat1Service;

    @Autowired
    ICaipiaoPl5Stat2Service iCaipiaoPl5Stat2Service;

    @Override
    public String stat1(Long qs, Integer jgCount) {
        /**
         * 先删除
         */
        if (jgCount == 0) {
            iCaipiaoPl5Stat1Service.removeAll();
        }

        QueryWrapper<CaipiaoPl5History> queryWrapper = new QueryWrapper<>();
        if (qs != null) {
            queryWrapper.lt("qs", qs);
        }
        queryWrapper.orderByAsc("qs");
        List<CaipiaoPl5History> caipiaoPl5Histories = caipiaoPl5HistoryMapper.selectList(queryWrapper);
        /**
         * 再添加
         */
        for (int i = 0; i < caipiaoPl5Histories.size() - (jgCount + 1); i++) {
            CaipiaoPl5History caipiaoPl5History = caipiaoPl5Histories.get(i);
            String kjNum = caipiaoPl5History.getKjNum();
            CaipiaoPl5History caipiaoPl5History1 = caipiaoPl5Histories.get(i + (jgCount + 1));
            String kjNum1 = caipiaoPl5History1.getKjNum();
            List<CaipiaoPl5Stat1> adds = new ArrayList<>();
            for (int k = 0; k < 5; k++) {
                int lastKjInt = Integer.parseInt(kjNum.substring(k, k + 1));
                //上一个号码奇偶
                int lastNumJo = lastKjInt % 2;
                //上一个号码012路： 分析号码除以3后的余数（0路:0,3,6,9; 1路:1,4,7; 2路:2,5,8）的分布情况
                int lastNumR012 = lastKjInt % 3;
                //上一个号码质合属性
                //质数：2、3、5、7、11、13、17、19、23、29
                int lastNumZhsx = Arrays.asList(2, 3, 5, 7, 11, 13, 17, 19, 23, 29).contains(lastKjInt) ? 1 : 0;
                for (int j = 0; j < 5; j++) {
                    String nextKjInt = kjNum1.substring(j, j + 1);
                    CaipiaoPl5Stat1 caipiaoPl5Stat1 = new CaipiaoPl5Stat1();
                    caipiaoPl5Stat1.setLastQs(caipiaoPl5History.getQs().intValue());
                    caipiaoPl5Stat1.setLastIndex(k);
                    caipiaoPl5Stat1.setLastNum(lastKjInt);
                    caipiaoPl5Stat1.setLastNumJo(lastNumJo);
                    caipiaoPl5Stat1.setLastNumR012(lastNumR012);
                    caipiaoPl5Stat1.setLastNumZhsx(lastNumZhsx);
                    caipiaoPl5Stat1.setNextIndex(j);
                    caipiaoPl5Stat1.setNextNum(Integer.parseInt(nextKjInt));
                    caipiaoPl5Stat1.setJgCount(jgCount);
                    adds.add(caipiaoPl5Stat1);
                }
            }
            iCaipiaoPl5Stat1Service.saveBatch(adds);
        }
        log.info("统计1，完成");
        return null;
    }

    @Override
    public String stat2(Long qs, Integer jgCount) {
        if (jgCount == 0) {
            iCaipiaoPl5Stat2Service.removeAll();
        }

        QueryWrapper<CaipiaoPl5History> queryWrapper = new QueryWrapper<>();
        if (qs != null) {
            queryWrapper.lt("qs", qs);
        }
        queryWrapper.orderByAsc("qs");
        List<CaipiaoPl5History> caipiaoPl5Histories = caipiaoPl5HistoryMapper.selectList(queryWrapper);
        List<CaipiaoPl5Stat2> adds = new ArrayList<>();

        for (int i = 0; i < caipiaoPl5Histories.size() - (1 + jgCount); i++) {
            CaipiaoPl5History caipiaoPl5History = caipiaoPl5Histories.get(i);
            String kjNum = caipiaoPl5History.getKjNum();
            CaipiaoPl5History caipiaoPl5History1 = caipiaoPl5Histories.get(i + (1 + jgCount));
            String kjNum1 = caipiaoPl5History1.getKjNum();
            /**
             * 和值特性
             */
            //开奖和值
            int sumValue = Integer.parseInt(kjNum.substring(0, 1)) + Integer.parseInt(kjNum.substring(1, 2)) + Integer.parseInt(kjNum.substring(2, 3));//+ Integer.parseInt(kjNum.substring(3,4)) + Integer.parseInt(kjNum.substring(4,5));
            //和值奇偶
            int sumJo = sumValue % 2;
            //和值012路： 分析号码除以3后的余数（0路:0,3,6,9; 1路:1,4,7; 2路:2,5,8）的分布情况
            int sumR012 = sumValue % 3;
            //和值质合属性
            //质数：2、3、5、7、11、13、17、19、23、29
            int sumZhsx = Arrays.asList(2, 3, 5, 7, 11, 13, 17, 19, 23, 29).contains(sumValue) ? 1 : 0;

            /**
             * 跨度值特性
             */
            List<String> numList = Arrays.asList(kjNum.substring(0, 1), kjNum.substring(1, 2), kjNum.substring(2, 3));
            Collections.sort(numList); //排序
            //跨度值
            int kdValue = Integer.parseInt(numList.get(2)) - Integer.parseInt(numList.get(0));
            //跨度奇偶
            int kdJo = kdValue % 2;
            //跨度012路： 分析号码除以3后的余数（0路:0,3,6,9; 1路:1,4,7; 2路:2,5,8）的分布情况
            int kdR012 = kdValue % 3;
            //跨度质合属性
            int kdZhsx = Arrays.asList(2, 3, 5, 7, 11, 13, 17, 19, 23, 29).contains(kdValue) ? 1 : 0;

            CaipiaoPl5Stat2 caipiaoPl5Stat2 = new CaipiaoPl5Stat2();
            caipiaoPl5Stat2.setId(IdUtil.getSnowflakeNextId());
            caipiaoPl5Stat2.setQs(caipiaoPl5History.getQs());
            caipiaoPl5Stat2.setSumValue(sumValue);
            caipiaoPl5Stat2.setSumJo(sumJo);
            caipiaoPl5Stat2.setSumR012(sumR012);
            caipiaoPl5Stat2.setSumZhPro(sumZhsx);
            caipiaoPl5Stat2.setKdValue(kdValue);
            caipiaoPl5Stat2.setKdJo(kdJo);
            caipiaoPl5Stat2.setKdR012(kdR012);
            caipiaoPl5Stat2.setKdZhPro(kdZhsx);
            caipiaoPl5Stat2.setNextP0(Integer.parseInt(kjNum1.substring(0, 1)));
            caipiaoPl5Stat2.setNextP1(Integer.parseInt(kjNum1.substring(1, 2)));
            caipiaoPl5Stat2.setNextP2(Integer.parseInt(kjNum1.substring(2, 3)));
            caipiaoPl5Stat2.setJgCount(jgCount);
            adds.add(caipiaoPl5Stat2);
        }
        iCaipiaoPl5Stat2Service.saveBatch(adds);
        log.info("统计2，完成");
        return null;
    }

    @Autowired
    CaipiaoPl5Stat1Mapper caipiaoPl5Stat1Mapper;

    @Autowired
    CaipiaoPl5Stat2Mapper caipiaoPl5Stat2Mapper;

    /**
     * @return
     */
    @Override
    public HashMap<String, Object> getYcKjNum(YuReqDTO yuReqDTO) {
        Map<String, Integer> map0 = new HashMap<>();
        Map<String, Integer> map1 = new HashMap<>();
        Map<String, Integer> map2 = new HashMap<>();

        /**
         * 预测期数 的 实际开奖号码
         */
        CaipiaoPl5History sjKj = this.baseMapper.selectById(yuReqDTO.getQs());

        /**
         * 1 统计1
         */
        CaipiaoPl5History lastQsHistory = getLastQsHistory(yuReqDTO.getQs(), yuReqDTO.getJgCount());
        //上一期的开奖号码
        String kjNum = lastQsHistory.getKjNum();

        int n0 = Integer.parseInt(kjNum.substring(0, 1));
        if (yuReqDTO.getCheckedCities().contains("各号码")) {
            List<CaipiaoPl5Stat1> ycList0 = caipiaoPl5Stat1Mapper.getYcKjNum(1, lastQsHistory.getQs(), n0, 0, yuReqDTO.getCt(), yuReqDTO.getJgCount());
            for (CaipiaoPl5Stat1 caipiaoPl5Stat1 : ycList0) {
                map0.merge(caipiaoPl5Stat1.getNextNum().toString(), caipiaoPl5Stat1.getCounts(), Integer::sum);
            }
        }
        int n0_jo = n0 % 2;
        if (yuReqDTO.getCheckedCities().contains("各号码奇偶")) {
            List<CaipiaoPl5Stat1> ycList0_jo = caipiaoPl5Stat1Mapper.getYcKjNum(2, lastQsHistory.getQs(), n0_jo, 0, yuReqDTO.getCt(), yuReqDTO.getJgCount());
            for (CaipiaoPl5Stat1 caipiaoPl5Stat1 : ycList0_jo) {
                map0.merge(caipiaoPl5Stat1.getNextNum().toString(), caipiaoPl5Stat1.getCounts(), Integer::sum);
            }
        }
        int n0_r012 = n0 % 3;
        if (yuReqDTO.getCheckedCities().contains("各号码012路")) {
            List<CaipiaoPl5Stat1> ycList0_r012 = caipiaoPl5Stat1Mapper.getYcKjNum(3, lastQsHistory.getQs(), n0_r012, 0, yuReqDTO.getCt(), yuReqDTO.getJgCount());
            for (CaipiaoPl5Stat1 caipiaoPl5Stat1 : ycList0_r012) {
                map0.merge(caipiaoPl5Stat1.getNextNum().toString(), caipiaoPl5Stat1.getCounts(), Integer::sum);
            }
        }
        int n0_zhsx = Arrays.asList(2, 3, 5, 7, 11, 13, 17, 19, 23, 29).contains(n0) ? 1 : 0;
        if (yuReqDTO.getCheckedCities().contains("各号码质合属性")) {
            List<CaipiaoPl5Stat1> ycList0_zhsx = caipiaoPl5Stat1Mapper.getYcKjNum(4, lastQsHistory.getQs(), n0_zhsx, 0, yuReqDTO.getCt(), yuReqDTO.getJgCount());
            for (CaipiaoPl5Stat1 caipiaoPl5Stat1 : ycList0_zhsx) {
                map0.merge(caipiaoPl5Stat1.getNextNum().toString(), caipiaoPl5Stat1.getCounts(), Integer::sum);
            }
        }

        int n1 = Integer.parseInt(kjNum.substring(1, 2));
        if (yuReqDTO.getCheckedCities().contains("各号码")) {
            List<CaipiaoPl5Stat1> ycList1 = caipiaoPl5Stat1Mapper.getYcKjNum(1, lastQsHistory.getQs(), n1, 1, yuReqDTO.getCt(), 0);
            for (CaipiaoPl5Stat1 caipiaoPl5Stat1 : ycList1) {
                map1.merge(caipiaoPl5Stat1.getNextNum().toString(), caipiaoPl5Stat1.getCounts(), Integer::sum);
            }
        }
        int n1_jo = n1 % 2;
        if (yuReqDTO.getCheckedCities().contains("各号码奇偶")) {
            List<CaipiaoPl5Stat1> ycList1_jo = caipiaoPl5Stat1Mapper.getYcKjNum(2, lastQsHistory.getQs(), n1_jo, 1, yuReqDTO.getCt(), yuReqDTO.getJgCount());
            for (CaipiaoPl5Stat1 caipiaoPl5Stat1 : ycList1_jo) {
                map1.merge(caipiaoPl5Stat1.getNextNum().toString(), caipiaoPl5Stat1.getCounts(), Integer::sum);
            }
        }
        int n1_r012 = n1 % 3;
        if (yuReqDTO.getCheckedCities().contains("各号码012路")) {
            List<CaipiaoPl5Stat1> ycList1_r012 = caipiaoPl5Stat1Mapper.getYcKjNum(3, lastQsHistory.getQs(), n1_r012, 1, yuReqDTO.getCt(), yuReqDTO.getJgCount());
            for (CaipiaoPl5Stat1 caipiaoPl5Stat1 : ycList1_r012) {
                map1.merge(caipiaoPl5Stat1.getNextNum().toString(), caipiaoPl5Stat1.getCounts(), Integer::sum);
            }
        }
        int n1_zhsx = Arrays.asList(2, 3, 5, 7, 11, 13, 17, 19, 23, 29).contains(n1) ? 1 : 0;
        if (yuReqDTO.getCheckedCities().contains("各号码质合属性")) {
            List<CaipiaoPl5Stat1> ycList1_zhsx = caipiaoPl5Stat1Mapper.getYcKjNum(4, lastQsHistory.getQs(), n1_zhsx, 1, yuReqDTO.getCt(), yuReqDTO.getJgCount());
            for (CaipiaoPl5Stat1 caipiaoPl5Stat1 : ycList1_zhsx) {
                map1.merge(caipiaoPl5Stat1.getNextNum().toString(), caipiaoPl5Stat1.getCounts(), Integer::sum);
            }
        }
        int n2 = Integer.parseInt(kjNum.substring(2, 3));
        if (yuReqDTO.getCheckedCities().contains("各号码")) {
            List<CaipiaoPl5Stat1> ycList2 = caipiaoPl5Stat1Mapper.getYcKjNum(1, lastQsHistory.getQs(), n2, 2, yuReqDTO.getCt(), yuReqDTO.getJgCount());
            for (CaipiaoPl5Stat1 caipiaoPl5Stat1 : ycList2) {
                map2.merge(caipiaoPl5Stat1.getNextNum().toString(), caipiaoPl5Stat1.getCounts(), Integer::sum);
            }
        }
        int n2_jo = n2 % 2;
        if (yuReqDTO.getCheckedCities().contains("各号码奇偶")) {
            List<CaipiaoPl5Stat1> ycList2_jo = caipiaoPl5Stat1Mapper.getYcKjNum(2, lastQsHistory.getQs(), n2_jo, 2, yuReqDTO.getCt(), yuReqDTO.getJgCount());
            for (CaipiaoPl5Stat1 caipiaoPl5Stat1 : ycList2_jo) {
                map2.merge(caipiaoPl5Stat1.getNextNum().toString(), caipiaoPl5Stat1.getCounts(), Integer::sum);
            }
        }
        int n2_r012 = n2 % 3;
        if (yuReqDTO.getCheckedCities().contains("各号码012路")) {
            List<CaipiaoPl5Stat1> ycList2_r012 = caipiaoPl5Stat1Mapper.getYcKjNum(3, lastQsHistory.getQs(), n2_r012, 2, yuReqDTO.getCt(), yuReqDTO.getJgCount());
            for (CaipiaoPl5Stat1 caipiaoPl5Stat1 : ycList2_r012) {
                map2.merge(caipiaoPl5Stat1.getNextNum().toString(), caipiaoPl5Stat1.getCounts(), Integer::sum);
            }
        }
        int n2_zhsx = Arrays.asList(2, 3, 5, 7, 11, 13, 17, 19, 23, 29).contains(n2) ? 1 : 0;
        if (yuReqDTO.getCheckedCities().contains("各号码质合属性")) {
            List<CaipiaoPl5Stat1> ycList2_zhsx = caipiaoPl5Stat1Mapper.getYcKjNum(4, lastQsHistory.getQs(), n2_zhsx, 2, yuReqDTO.getCt(), yuReqDTO.getJgCount());
            for (CaipiaoPl5Stat1 caipiaoPl5Stat1 : ycList2_zhsx) {
                map2.merge(caipiaoPl5Stat1.getNextNum().toString(), caipiaoPl5Stat1.getCounts(), Integer::sum);
            }
        }

        /**
         * 和值属性
         */
        //开奖和值
        int sumValue = Integer.parseInt(kjNum.substring(0, 1)) + Integer.parseInt(kjNum.substring(1, 2)) + Integer.parseInt(kjNum.substring(2, 3));//+ Integer.parseInt(kjNum.substring(3,4)) + Integer.parseInt(kjNum.substring(4,5));
        //和值奇偶
        int sumJo = sumValue % 2;
        //和值012路： 分析号码除以3后的余数（0路:0,3,6,9; 1路:1,4,7; 2路:2,5,8）的分布情况
        int sumR012 = sumValue % 3;
        //和值质合属性
        //质数：2、3、5、7、11、13、17、19、23、29
        int sumZhsx = Arrays.asList(2, 3, 5, 7, 11, 13, 17, 19, 23, 29).contains(sumValue) ? 1 : 0;

        if (yuReqDTO.getCheckedCities().contains("和值")) {
            List<CaipiaoPl5Stat2> tj2SumValue_0 = caipiaoPl5Stat2Mapper.getYcKjNumSumValue(1, lastQsHistory.getQs(), sumValue, 0, yuReqDTO.getCt(), yuReqDTO.getJgCount());
            for (CaipiaoPl5Stat2 caipiaoPl5Stat2 : tj2SumValue_0) {
                map0.merge(caipiaoPl5Stat2.getNextP0().toString(), caipiaoPl5Stat2.getCounts(), Integer::sum);
            }
            List<CaipiaoPl5Stat2> tj2SumValue_1 = caipiaoPl5Stat2Mapper.getYcKjNumSumValue(1, lastQsHistory.getQs(), sumValue, 1, yuReqDTO.getCt(), yuReqDTO.getJgCount());
            for (CaipiaoPl5Stat2 caipiaoPl5Stat2 : tj2SumValue_1) {
                map1.merge(caipiaoPl5Stat2.getNextP1().toString(), caipiaoPl5Stat2.getCounts(), Integer::sum);
            }
            List<CaipiaoPl5Stat2> tj2SumValue_2 = caipiaoPl5Stat2Mapper.getYcKjNumSumValue(1, lastQsHistory.getQs(), sumValue, 2, yuReqDTO.getCt(), yuReqDTO.getJgCount());
            for (CaipiaoPl5Stat2 caipiaoPl5Stat2 : tj2SumValue_2) {
                map2.merge(caipiaoPl5Stat2.getNextP2().toString(), caipiaoPl5Stat2.getCounts(), Integer::sum);
            }
        }

        if (yuReqDTO.getCheckedCities().contains("和值奇偶")) {
            List<CaipiaoPl5Stat2> tj2SumJo_0 = caipiaoPl5Stat2Mapper.getYcKjNumSumValue(2, lastQsHistory.getQs(), sumJo, 0, yuReqDTO.getCt(), yuReqDTO.getJgCount());
            for (CaipiaoPl5Stat2 caipiaoPl5Stat2 : tj2SumJo_0) {
                map0.merge(caipiaoPl5Stat2.getNextP0().toString(), caipiaoPl5Stat2.getCounts(), Integer::sum);
            }
            List<CaipiaoPl5Stat2> tj2SumJo_1 = caipiaoPl5Stat2Mapper.getYcKjNumSumValue(2, lastQsHistory.getQs(), sumJo, 1, yuReqDTO.getCt(), yuReqDTO.getJgCount());
            for (CaipiaoPl5Stat2 caipiaoPl5Stat2 : tj2SumJo_1) {
                map1.merge(caipiaoPl5Stat2.getNextP1().toString(), caipiaoPl5Stat2.getCounts(), Integer::sum);
            }
            List<CaipiaoPl5Stat2> tj2SumJo_2 = caipiaoPl5Stat2Mapper.getYcKjNumSumValue(2, lastQsHistory.getQs(), sumJo, 2, yuReqDTO.getCt(), yuReqDTO.getJgCount());
            for (CaipiaoPl5Stat2 caipiaoPl5Stat2 : tj2SumJo_2) {
                map2.merge(caipiaoPl5Stat2.getNextP2().toString(), caipiaoPl5Stat2.getCounts(), Integer::sum);
            }
        }

        if (yuReqDTO.getCheckedCities().contains("和值012路")) {
            List<CaipiaoPl5Stat2> tj2SumR012_0 = caipiaoPl5Stat2Mapper.getYcKjNumSumValue(3, lastQsHistory.getQs(), sumR012, 0, yuReqDTO.getCt(), yuReqDTO.getJgCount());
            for (CaipiaoPl5Stat2 caipiaoPl5Stat2 : tj2SumR012_0) {
                map0.merge(caipiaoPl5Stat2.getNextP0().toString(), caipiaoPl5Stat2.getCounts(), Integer::sum);
            }
            List<CaipiaoPl5Stat2> tj2SumR012_1 = caipiaoPl5Stat2Mapper.getYcKjNumSumValue(3, lastQsHistory.getQs(), sumR012, 1, yuReqDTO.getCt(), yuReqDTO.getJgCount());
            for (CaipiaoPl5Stat2 caipiaoPl5Stat2 : tj2SumR012_1) {
                map1.merge(caipiaoPl5Stat2.getNextP1().toString(), caipiaoPl5Stat2.getCounts(), Integer::sum);
            }
            List<CaipiaoPl5Stat2> tj2SumR012_2 = caipiaoPl5Stat2Mapper.getYcKjNumSumValue(3, lastQsHistory.getQs(), sumR012, 2, yuReqDTO.getCt(), yuReqDTO.getJgCount());
            for (CaipiaoPl5Stat2 caipiaoPl5Stat2 : tj2SumR012_2) {
                map2.merge(caipiaoPl5Stat2.getNextP2().toString(), caipiaoPl5Stat2.getCounts(), Integer::sum);
            }
        }

        if (yuReqDTO.getCheckedCities().contains("和值质合属性")) {
            List<CaipiaoPl5Stat2> tj2SumZhsx_0 = caipiaoPl5Stat2Mapper.getYcKjNumSumValue(4, lastQsHistory.getQs(), sumZhsx, 0, yuReqDTO.getCt(), yuReqDTO.getJgCount());
            for (CaipiaoPl5Stat2 caipiaoPl5Stat2 : tj2SumZhsx_0) {
                map0.merge(caipiaoPl5Stat2.getNextP0().toString(), caipiaoPl5Stat2.getCounts(), Integer::sum);
            }
            List<CaipiaoPl5Stat2> tj2SumZhsx_1 = caipiaoPl5Stat2Mapper.getYcKjNumSumValue(4, lastQsHistory.getQs(), sumZhsx, 1, yuReqDTO.getCt(), yuReqDTO.getJgCount());
            for (CaipiaoPl5Stat2 caipiaoPl5Stat2 : tj2SumZhsx_1) {
                map1.merge(caipiaoPl5Stat2.getNextP1().toString(), caipiaoPl5Stat2.getCounts(), Integer::sum);
            }
            List<CaipiaoPl5Stat2> tj2SumZhsx_2 = caipiaoPl5Stat2Mapper.getYcKjNumSumValue(4, lastQsHistory.getQs(), sumZhsx, 2, yuReqDTO.getCt(), yuReqDTO.getJgCount());
            for (CaipiaoPl5Stat2 caipiaoPl5Stat2 : tj2SumZhsx_2) {
                map2.merge(caipiaoPl5Stat2.getNextP2().toString(), caipiaoPl5Stat2.getCounts(), Integer::sum);
            }
        }
        /**
         * 跨度值属性
         */
        List<String> numList = Arrays.asList(kjNum.substring(0, 1), kjNum.substring(1, 2), kjNum.substring(2, 3));
        Collections.sort(numList); //排序
        //跨度值
        int kdValue = Integer.parseInt(numList.get(2)) - Integer.parseInt(numList.get(0));
        //跨度奇偶
        int kdJo = kdValue % 2;
        //跨度012路： 分析号码除以3后的余数（0路:0,3,6,9; 1路:1,4,7; 2路:2,5,8）的分布情况
        int kdR012 = kdValue % 3;
        //跨度质合属性
        int kdZhsx = Arrays.asList(2, 3, 5, 7, 11, 13, 17, 19, 23, 29).contains(kdValue) ? 1 : 0;

        if (yuReqDTO.getCheckedCities().contains("跨度值")) {
            List<CaipiaoPl5Stat2> tj2KdValue_0 = caipiaoPl5Stat2Mapper.getYcKjNumSumValue(5, lastQsHistory.getQs(), kdValue, 0, yuReqDTO.getCt(), yuReqDTO.getJgCount());
            for (CaipiaoPl5Stat2 caipiaoPl5Stat2 : tj2KdValue_0) {
                map0.merge(caipiaoPl5Stat2.getNextP0().toString(), caipiaoPl5Stat2.getCounts(), Integer::sum);
            }
            List<CaipiaoPl5Stat2> tj2KdValue_1 = caipiaoPl5Stat2Mapper.getYcKjNumSumValue(5, lastQsHistory.getQs(), kdValue, 1, yuReqDTO.getCt(), yuReqDTO.getJgCount());
            for (CaipiaoPl5Stat2 caipiaoPl5Stat2 : tj2KdValue_1) {
                map1.merge(caipiaoPl5Stat2.getNextP1().toString(), caipiaoPl5Stat2.getCounts(), Integer::sum);
            }
            List<CaipiaoPl5Stat2> tj2KdValue_2 = caipiaoPl5Stat2Mapper.getYcKjNumSumValue(5, lastQsHistory.getQs(), kdValue, 2, yuReqDTO.getCt(), yuReqDTO.getJgCount());
            for (CaipiaoPl5Stat2 caipiaoPl5Stat2 : tj2KdValue_2) {
                map2.merge(caipiaoPl5Stat2.getNextP2().toString(), caipiaoPl5Stat2.getCounts(), Integer::sum);
            }
        }

        if (yuReqDTO.getCheckedCities().contains("跨度奇偶")) {
            List<CaipiaoPl5Stat2> tj2KdJo_0 = caipiaoPl5Stat2Mapper.getYcKjNumSumValue(6, lastQsHistory.getQs(), kdJo, 0, yuReqDTO.getCt(), yuReqDTO.getJgCount());
            for (CaipiaoPl5Stat2 caipiaoPl5Stat2 : tj2KdJo_0) {
                map0.merge(caipiaoPl5Stat2.getNextP0().toString(), caipiaoPl5Stat2.getCounts(), Integer::sum);
            }
            List<CaipiaoPl5Stat2> tj2KdJo_1 = caipiaoPl5Stat2Mapper.getYcKjNumSumValue(6, lastQsHistory.getQs(), kdJo, 1, yuReqDTO.getCt(), yuReqDTO.getJgCount());
            for (CaipiaoPl5Stat2 caipiaoPl5Stat2 : tj2KdJo_1) {
                map1.merge(caipiaoPl5Stat2.getNextP1().toString(), caipiaoPl5Stat2.getCounts(), Integer::sum);
            }
            List<CaipiaoPl5Stat2> tj2KdJo_2 = caipiaoPl5Stat2Mapper.getYcKjNumSumValue(6, lastQsHistory.getQs(), kdJo, 2, yuReqDTO.getCt(), yuReqDTO.getJgCount());
            for (CaipiaoPl5Stat2 caipiaoPl5Stat2 : tj2KdJo_2) {
                map2.merge(caipiaoPl5Stat2.getNextP2().toString(), caipiaoPl5Stat2.getCounts(), Integer::sum);
            }
        }

        if (yuReqDTO.getCheckedCities().contains("跨度012路")) {
            List<CaipiaoPl5Stat2> tj2KdR012_0 = caipiaoPl5Stat2Mapper.getYcKjNumSumValue(7, lastQsHistory.getQs(), kdR012, 0, yuReqDTO.getCt(), yuReqDTO.getJgCount());
            for (CaipiaoPl5Stat2 caipiaoPl5Stat2 : tj2KdR012_0) {
                map0.merge(caipiaoPl5Stat2.getNextP0().toString(), caipiaoPl5Stat2.getCounts(), Integer::sum);
            }
            List<CaipiaoPl5Stat2> tj2KdR012_1 = caipiaoPl5Stat2Mapper.getYcKjNumSumValue(7, lastQsHistory.getQs(), kdR012, 1, yuReqDTO.getCt(), yuReqDTO.getJgCount());
            for (CaipiaoPl5Stat2 caipiaoPl5Stat2 : tj2KdR012_1) {
                map1.merge(caipiaoPl5Stat2.getNextP1().toString(), caipiaoPl5Stat2.getCounts(), Integer::sum);
            }
            List<CaipiaoPl5Stat2> tj2KdR012_2 = caipiaoPl5Stat2Mapper.getYcKjNumSumValue(7, lastQsHistory.getQs(), kdR012, 2, yuReqDTO.getCt(), yuReqDTO.getJgCount());
            for (CaipiaoPl5Stat2 caipiaoPl5Stat2 : tj2KdR012_2) {
                map2.merge(caipiaoPl5Stat2.getNextP2().toString(), caipiaoPl5Stat2.getCounts(), Integer::sum);
            }
        }

        if (yuReqDTO.getCheckedCities().contains("跨度质合属性")) {
            List<CaipiaoPl5Stat2> tj2KdkdZhsx_0 = caipiaoPl5Stat2Mapper.getYcKjNumSumValue(8, lastQsHistory.getQs(), kdZhsx, 0, yuReqDTO.getCt(), yuReqDTO.getJgCount());
            for (CaipiaoPl5Stat2 caipiaoPl5Stat2 : tj2KdkdZhsx_0) {
                map0.merge(caipiaoPl5Stat2.getNextP0().toString(), caipiaoPl5Stat2.getCounts(), Integer::sum);
            }
            List<CaipiaoPl5Stat2> tj2KdkdZhsx_1 = caipiaoPl5Stat2Mapper.getYcKjNumSumValue(8, lastQsHistory.getQs(), kdZhsx, 1, yuReqDTO.getCt(), yuReqDTO.getJgCount());
            for (CaipiaoPl5Stat2 caipiaoPl5Stat2 : tj2KdkdZhsx_1) {
                map1.merge(caipiaoPl5Stat2.getNextP1().toString(), caipiaoPl5Stat2.getCounts(), Integer::sum);
            }
            List<CaipiaoPl5Stat2> tj2KdkdZhsx_2 = caipiaoPl5Stat2Mapper.getYcKjNumSumValue(8, lastQsHistory.getQs(), kdZhsx, 2, yuReqDTO.getCt(), yuReqDTO.getJgCount());
            for (CaipiaoPl5Stat2 caipiaoPl5Stat2 : tj2KdkdZhsx_2) {
                map2.merge(caipiaoPl5Stat2.getNextP2().toString(), caipiaoPl5Stat2.getCounts(), Integer::sum);
            }
        }

        List<String> keyList0 = MapValueSortUtil.sortMapByValue(map0, "desc");
        List<String> keyList1 = MapValueSortUtil.sortMapByValue(map1, "desc");
        List<String> keyList2 = MapValueSortUtil.sortMapByValue(map2, "desc");

        HashMap<String, Object> r = new HashMap<>();
        r.put("p0", keyList0);
        r.put("p1", keyList1);
        r.put("p2", keyList2);
        r.put("sjkjNum", sjKj == null ? "" : sjKj.getKjNum().substring(0, 3));


        //获取最近10期出现的热号  和 冷号
        QueryWrapper<CaipiaoPl5History> queryWrapper = new QueryWrapper<>();
        queryWrapper.lt("qs", yuReqDTO.getQs());
        queryWrapper.orderByDesc("qs");
        queryWrapper.last("limit 10");
        List<CaipiaoPl5History> list = this.list(queryWrapper);
        Map<String, Integer> rMap0 = new HashMap<>();
        Map<String, Integer> rMap1 = new HashMap<>();
        Map<String, Integer> rMap2 = new HashMap<>();
        for (CaipiaoPl5History caipiaoPl5History : list) {
            String p0 = caipiaoPl5History.getKjNum().substring(0, 1);
            String p1 = caipiaoPl5History.getKjNum().substring(1, 2);
            String p2 = caipiaoPl5History.getKjNum().substring(2, 3);
            rMap0.merge(p0, 1, Integer::sum);
            rMap1.merge(p1, 1, Integer::sum);
            rMap2.merge(p2, 1, Integer::sum);
        }
        List<String> r0 = MapValueSortUtil.sortMapByValue(rMap0, "desc");
        List<String> r1 = MapValueSortUtil.sortMapByValue(rMap1, "desc");
        List<String> r2 = MapValueSortUtil.sortMapByValue(rMap2, "desc");
        r.put("rr0", r0);
        r.put("rr1", r1);
        r.put("rr2", r2);

        //冷号
        List<String> l0 = MapValueSortUtil.sortMapByValue(rMap0, "asc");
        List<String> l1 = MapValueSortUtil.sortMapByValue(rMap1, "asc");
        List<String> l2 = MapValueSortUtil.sortMapByValue(rMap2, "asc");
        List<Integer> allNum = Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
        List<String> ll0 = new ArrayList<>();
        List<String> ll1 = new ArrayList<>();
        List<String> ll2 = new ArrayList<>();
        for (Integer i : allNum) {
            if (!l0.contains(i.toString())) {
                ll0.add(i.toString());
            }
            if (!l1.contains(i.toString())) {
                ll1.add(i.toString());
            }
            if (!l2.contains(i.toString())) {
                ll2.add(i.toString());
            }
        }
        ll0.addAll(l0);
        ll1.addAll(l1);
        ll2.addAll(l2);
        r.put("ll0", ll0);
        r.put("ll1", ll1);
        r.put("ll2", ll2);


        HashSet<String> zzp0 = new HashSet<>(this.getSubList(yuReqDTO, keyList0, 0));
        HashSet<String> zzp1 = new HashSet<>(this.getSubList(yuReqDTO, keyList1, 0));
        HashSet<String> zzp2 = new HashSet<>(this.getSubList(yuReqDTO, keyList2, 0));

        /**
         * 预测号码和热号交集， 然后，和 热号反集进行并集
         */
//        zzp0.retainAll(r0);
//        zzp1.retainAll(r1);
//        zzp2.retainAll(r2);
//        zzp0.addAll(this.getFj(r0));
//        zzp1.addAll(this.getFj(r1));
//        zzp2.addAll(this.getFj(r2));
        //热号
        zzp0.addAll(this.getSubList(yuReqDTO, r0, 0));
        zzp1.addAll(this.getSubList(yuReqDTO, r1, 0));
        zzp2.addAll(this.getSubList(yuReqDTO, r2, 0));

        //冷号
        zzp0.addAll(this.getSubList(yuReqDTO, ll0, 0));
        zzp1.addAll(this.getSubList(yuReqDTO, ll1, 0));
        zzp2.addAll(this.getSubList(yuReqDTO, ll2, 0));

        r.put("zzp0", zzp0);
        r.put("zzp1", zzp1);
        r.put("zzp2", zzp2);


        r.put("lr", 1040 - zzp0.size() * zzp1.size() * zzp2.size() * 2);
        r.put("tr", zzp0.size() * zzp1.size() * zzp2.size() * 2);
        if(sjKj != null) {
            if (zzp0.contains(sjKj.getKjNum().substring(0, 1))
                    && zzp1.contains(sjKj.getKjNum().substring(1, 2))
                    && zzp2.contains(sjKj.getKjNum().substring(2, 3))) {
                r.put("sfzj", "中奖");
            } else {
                r.put("sfzj", "未中奖");
            }
        }


        return r;
    }

    private static HashSet<String> getJj(List<String> r0, List<String> ll0) {
        HashSet<String> sss0 = new HashSet<>(r0);
        sss0.retainAll(new HashSet<>(ll0.subList(ll0.size() - 8, ll0.size())));
        return sss0;
    }

    private Set<String> getFj(List<String> r0) {
        List<Integer> allNum = Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
        HashSet<String> set = new HashSet<>();
        for (String s : r0) {
            if (allNum.contains(Integer.parseInt(s))) {
                set.add(s);
            }
        }
        return set;
    }

    private List<String> getSubList(YuReqDTO yuReqDTO, List<String> keyList0, int offset) {
        return keyList0.size() > (yuReqDTO.getLrct() + offset) ? keyList0.subList(0, yuReqDTO.getLrct() + offset) : keyList0;
    }

    private List<String> getSubList2(YuReqDTO yuReqDTO, List<String> keyList0, int offset) {
        if (keyList0.size() > (yuReqDTO.getLrct() + offset)) {
            return keyList0.subList(keyList0.size() - yuReqDTO.getLrct() - offset, keyList0.size());
        }
        return keyList0;
    }

    private CaipiaoPl5History getLastQsHistory(Long qs, Integer jgCount) {
        QueryWrapper<CaipiaoPl5History> queryWrapper = new QueryWrapper<>();
        queryWrapper.lt("qs", qs);
        queryWrapper.orderByDesc("qs");
        queryWrapper.last(" limit 100");
        List<CaipiaoPl5History> caipiaoPl5Histories = caipiaoPl5HistoryMapper.selectList(queryWrapper);
        return caipiaoPl5Histories.get(jgCount);//根据间隔期数获取参考号码
    }
}
